home *** CD-ROM | disk | FTP | other *** search
- Path: lll-winken!ames!mailrus!tut.cis.ohio-state.edu!ucbvax!unisoft!uunet!allbery
- From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Newsgroups: comp.sources.misc
- Subject: v06i031: redir - redirect stdout and stderr separately
- Message-ID: <48160@uunet.UU.NET>
- Date: 4 Feb 89 03:12:04 GMT
- Sender: allbery@uunet.UU.NET
- Reply-To: bobg+@andrew.cmu.edu
- Lines: 328
- Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 6, Issue 31
- Submitted-by: bobg+@andrew.cmu.edu
- Archive-name: redir
-
- This is redir, a simple Unix program for csh(1) users who are tired of being
- sneered at by their sh(1)-using brothers because their shell can't separate
- stdout from stderr. Redir will exec a program you name, redirecting the
- standard output and/or the standard error (or neither) according to redir's
- options. Previously, the only good way of separating stdout from stderr in csh
- was something like
-
- (command > stdout-destination) >& stderr-destination
-
- which stinks. Suppose you wanted to pipe command A through command B,
- collecting the stderr of A in A.err and the stderr of B in B.err, while
- displaying the stdout of B? What would you do then, huh? Probably something
- awful that looks like this:
-
- (A | (B > /dev/tyy) >& B.err) >& A.err
-
- I'm not even sure that would work. I am sure that this works:
-
- redir -e A.err A | redir -e B.err B
-
- Well, here it is.
-
- ----- Not this line -----
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: README Makefile redir.c redir.doc
- # Wrapped by bobg@ephrata.andrew.cmu.edu on Sun Jan 29 19:02:42 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f README -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README\"
- else
- echo shar: Extracting \"README\" \(893 characters\)
- sed "s/^X//" >README <<'END_OF_README'
- XRedir is a simple utility which remedies a problem in csh(1);
- Xnamely, that you can't redirect stdout and stderr separately,
- Xas you can in sh(1), unless you want to do something ugly like
- X
- X (command > stdout) >& stderr
- X
- XRedir will execute the command you name, with stdout and
- Xstderr redirected according to the options you supply to redir.
- XThe file redir.doc gives the usage of this program.
- X
- XTo compile this program, type "make redir". To install this
- Xprogram on your system, modify the Makefile so that the
- Xvariables BIN and DOC are defined to be the pathnames
- Xof the directories to hold the binary file "redir" and the
- Xdocumentation file "redir.doc," respectively, then type
- X"make install".
- X
- XThis software exists in the public domain. Absolutely no
- Xrestrictions on its usage, modification or distribution
- Xexist. No guarantees are made concerning the proper
- Xfunctioning of this software.
- END_OF_README
- if test 893 -ne `wc -c <README`; then
- echo shar: \"README\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- echo shar: Extracting \"Makefile\" \(350 characters\)
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- XOPTIMIZE = -O
- XDEBUG =
- XINCLUDES =
- XPROFILE =
- XLIBS =
- XCFLAGS = $(OPTIMIZE) $(DEBUG) $(INCLUDES) $(PROFILE)
- XCC = cc
- XBIN =
- XDOC =
- X
- XTARGET = redir
- X
- Xredir: redir.c
- X $(CC) $(CFLAGS) -o redir redir.c
- X
- Xtest: $(TARGET)
- X
- Xinstall: $(TARGET)
- X cp $(TARGET) $(BIN)
- X -strip $(BIN)/$(TARGET)
- X cp redir.doc $(DOC)
- X
- Xclean:
- X -rm -f *.BAK *.CKP *.o a.out gmon.out $(TARGET)
- END_OF_Makefile
- if test 350 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f redir.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"redir.c\"
- else
- echo shar: Extracting \"redir.c\" \(3851 characters\)
- sed "s/^X//" >redir.c <<'END_OF_redir.c'
- X/* redir
- X * a program to execute a command, redirecting stdout and stderr separately,
- X * a feature available in sh but not csh.
- X *
- X * THIS SOFTWARE EXISTS IN THE PUBLIC DOMAIN. ABSOLUTELY NO
- X * RESTRICTIONS ON ITS USAGE, MODIFICATION OR DISTRIBUTION
- X * EXIST. NO GUARANTEES ARE MADE CONCERNING THE PROPER
- X * FUNCTIONING OF THIS SOFTWARE.
- X *
- X * Usage:
- X *
- X * redir [options] command-words...
- X *
- X * where options are
- X * -o file
- X * to redirect stdout to file "file," without clobbering "file" if it exists
- X * -e file
- X * to redirect stderr to file "file," without clobbering "file" if it exists
- X * -O file
- X * to redirect stdout to file "file," clobbering "file" if it exists
- X * -E file
- X * to redirect stderr to file "file," clobbering "file" if it exists
- X * -a
- X * the following redirection option is to append to the named file, as in:
- X * redir -O foo.log -ae foo.err command command-arg1 command-arg2 ...
- X * (stdout (destructively) to foo.log, stderr appended to foo.err.
- X * The -a option doesn't care if the named file exists or not. This option
- X * must be used twice if you want stdout and stderr both to be appended
- X * to their respective files;
- X * redir -ao foo.log -ae foo.err command ...
- X */
- X
- X#include <stdio.h>
- X#include <sys/file.h>
- X
- X#define USAGESTRING ("Usage: %s [-[a][oeOE] file] ... command-words\n")
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X extern int optind;
- X extern char *optarg;
- X char *stderrfile = NULL, *stdoutfile = NULL;
- X int rstderr = 0, rstdout = 0, cstderr = 0, cstdout = 0, astderr
- = 0, astdout = 0, appendopt = 0, c, fd;
- X
- X while ((c = getopt(argc, argv, "ao:e:O:E:")) != EOF) {
- X switch (c) {
- X case 'a':
- X if (appendopt) {
- X fprintf(stderr, USAGESTRING, argv[0]);
- X exit(1);
- X }
- X ++appendopt;
- X break;
- X case 'e':
- X if (rstderr) {
- X fprintf(stderr, USAGESTRING, argv[0]);
- X exit(1);
- X }
- X ++rstderr;
- X stderrfile = optarg;
- X if (appendopt) {
- X appendopt = 0;
- X ++astderr;
- X }
- X break;
- X case 'o':
- X if (rstdout) {
- X fprintf(stderr, USAGESTRING, argv[0]);
- X exit(1);
- X }
- X ++rstdout;
- X stdoutfile = optarg;
- X if (appendopt) {
- X appendopt = 0;
- X ++astdout;
- X }
- X break;
- X case 'E':
- X if (rstderr) {
- X fprintf(stderr, USAGESTRING, argv[0]);
- X exit(1);
- X }
- X ++rstderr;
- X ++cstderr;
- X stderrfile = optarg;
- X if (appendopt) {
- X appendopt = 0;
- X ++astderr;
- X }
- X break;
- X case 'O':
- X if (rstdout) {
- X fprintf(stderr, USAGESTRING, argv[0]);
- X exit(1);
- X }
- X ++rstdout;
- X ++cstdout;
- X stdoutfile = optarg;
- X if (appendopt) {
- X appendopt = 0;
- X ++astdout;
- X }
- X break;
- X default:
- X fprintf(stderr, USAGESTRING, argv[0]);
- X exit(1);
- X break;
- X }
- X }
- X if (rstdout) {
- X if ((fd = open(stdoutfile, (astdout ?
- X (O_WRONLY | O_APPEND | O_CREAT) :
- X (cstdout ?
- X (O_WRONLY | O_CREAT | O_TRUNC) :
- X (O_WRONLY | O_CREAT | O_EXCL))),
- X 0644)) < 0) {
- X fprintf(stderr,
- X "%s: couldn't open destination %s for standard output\n",
- X argv[0], stdoutfile);
- X exit(2);
- X }
- X if (dup2(fd, 1) < 0) {
- X fprintf(stderr,
- X "%s: couldn't open destination %s for standard output\n",
- X argv[0], stdoutfile);
- X exit(2);
- X }
- X close(fd);
- X }
- X if (rstderr) {
- X if ((fd = open(stderrfile, (astderr ?
- X (O_WRONLY | O_APPEND | O_CREAT) :
- X (cstderr ?
- X (O_WRONLY | O_CREAT | O_TRUNC) :
- X (O_WRONLY | O_CREAT | O_EXCL))),
- X 0644)) < 0) {
- X fprintf(stderr,
- X "%s: couldn't open destination %s for standard error\n",
- X argv[0], stderrfile);
- X exit(2);
- X }
- X if (dup2(fd, 2) < 0) {
- X fprintf(stderr,
- X "%s: couldn't open destination %s for standard error\n",
- X argv[0], stderrfile);
- X exit(2);
- X }
- X close(fd);
- X }
- X execvp(argv[optind], argv + optind);
- X}
- END_OF_redir.c
- if test 3851 -ne `wc -c <redir.c`; then
- echo shar: \"redir.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f redir.doc -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"redir.doc\"
- else
- echo shar: Extracting \"redir.doc\" \(1658 characters\)
- sed "s/^X//" >redir.doc <<'END_OF_redir.doc'
- XREDIR(1)
- X
- XNAME
- Xredir - redirect standard output and/or standard error (diagnostic output)
- X
- XSYNOPSIS
- Xredir [-[a][oeOE] file] ... command arg1 arg2 ...
- X
- XDESCRIPTION
- XRedir executes the named command with the given arguments,
- Xredirecting the standard output and/or standard input according
- Xto the options given. This program exists to remedy a serious
- Xdeficiency in csh(1), namely that csh does not allow stdout
- Xand stderr to be redirected separately. The options are:
- X
- X-o file Redirect the standard output of the named command
- X to the file "file", only if "file" does not yet exist.
- X-O file Redirect the standard output of the named command
- X to the file "file", clobbering the existing
- X version of "file" if it exists.
- X-e Redirect the standard error (diagnostic output) of the
- X named command to file "file", only if "file" does not yet exist.
- X-E Redirect the standard error (diagnostic output) of the
- X named command to the file "file", clobbering the existing
- X version of "file" if it exists.
- X-ao file Append the standard output of the named command
- X to the file "file", whether or not "file" exists.
- X-ae file Append the standard error (diagnostic output) of the
- X named command to the file "file", whether or not "file" exists.
- X
- X-aO and -aE are synonyms for -ao and -ae.
- X
- XEXAMPLE
- XThe following example demonstrates a means for piping the output
- Xof sed through ctags and then into awk; errors from ctags will be
- Xplaced in the file "errors":
- X
- X% ... | sed -f sed-script | redir -e errors ctags -x | awk -f awk-script | ...
- X
- XAUTHOR
- XBob Glickstein
- X Information Technology Center
- X Carnegie Mellon University
- X Pittsburgh, PA
- X 22-Jan-89
- X ARPAnet: bobg@andrew.cmu.edu
- END_OF_redir.doc
- if test 1658 -ne `wc -c <redir.doc`; then
- echo shar: \"redir.doc\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-